﻿using System;
using Ewk.Configuration;
using Rhino.Mocks;

namespace Ewk.UnitTests
{
    public class MockHelper : IDisposable
    {
        private MockRepository _mockRepository;
        private IDependencyResolver _dependencyResolver;

        public MockHelper()
        {
            _mockRepository = new MockRepository();
            _dependencyResolver = _mockRepository.DynamicMock<IDependencyResolver>();
            DependencyConfiguration.DependencyResolver = _dependencyResolver;
        }

        public T CreateMock<T>() where T : class
        {
            return _mockRepository.DynamicMock<T>();
        }

        public T CreateAndRegisterMock<T>() where T : class
        {
            var mock = CreateMock<T>();

            RegisterInstance(mock);

            return mock;
        }

        public void RegisterInstance<T>(T instance) where T : class
        {
            RegisterInstanceCreator(() => instance);
        }

        public void RegisterInstanceCreator<T>(Func<T> creator) where T : class
        {
            _dependencyResolver
                .Expect(d =>
                        d.Resolve<T>(Arg<DependencyResolverParameterOverride[]>.Is.Anything))
                .Return(creator())
                .Repeat.Any();

            _dependencyResolver
                .Expect(d =>
                        d.Resolve<T>(
                            Arg<string>.Is.Anything,
                            Arg<DependencyResolverParameterOverride[]>.Is.Anything))
                .Return(creator())
                .Repeat.Any();

            _dependencyResolver.Replay();
        }

        public void Replay()
        {
            _dependencyResolver.Replay();
        }

        #region Implementation of IDisposable

        public void Dispose()
        {
            _mockRepository = null;
            _dependencyResolver.Dispose();
            _dependencyResolver = null;
        }

        #endregion
    }
}